<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>Proxy</h2>
    <p>一个Proxy 对象由俩个部分组成：target、handler。在通过Proxy构造函数生成实例对象时，需要提供这俩个参数</p>
    <p>target即目标对象，handler是一个对象，声明了代理target的指定行为。</p>
</body>
<script>
    let target = {
        name: 'Tom',
        age: 24
    }
    let handler = {
        get: function(target, key) {
            console.log('getting' +key);
            return target[key]; //不是target.key
        },
        set: function(target, key, value) {
            console.log('setting' +key);
            target[key] = value;
        }
    }

    let proxy = new Proxy(target, handler)
    proxy.name  //实际执行 handler.get
    proxy.age = 25 //实际执行 handler.set
    // getting name
    //setting age
    // 25

    //target 可以为空对象
    let targetEpt = {}
    let proxyEpt = new Proxy(targetEpt, handler)
    //调用get方法。此时目标对象为空，没有name属性
    proxyEpt.name //getting name
    //调用set方法，向目标对象中添加了 name属性
    proxyEpt.name = 'Tom'
    //setting name
    // 'Tom'
    //再次调用get ，此时已经存在name属性
    proxyEpt.name
    //getting name
    //'Tom'

    //通过构造函数新建实例时其实是对目标对象进行了浅拷贝，因此目标对象与代理对象会互相影响
    targetEpt
    // {name: 'Tom'}

    //handler 对象也可以为空，相当于不设置拦截操作，直接访问目标对象
    let targetEmpty = {}
    let proxyEmpty = new Proxy(targetEmpty, {})
    proxyEmpty.name = 'Tom'
    targetEmpty // {name : "Tom"}
</script>
</html>